package modules

import (
	"fastdp-ops/cmd/agent/zaplog"
	"fastdp-ops/pkg/agent/utils"
	pb "fastdp-ops/proto/exec"
	"os/exec"
	"strings"
)

// ShellModule 实现 Module 接口，用于执行命令
type ShellModule struct {
}

// NewShellModule 创建 Shell 模块实例
func NewShellModule() Module {
	return &ShellModule{}
}

func (m *ShellModule) Run(req *pb.Execrequest) (*pb.ExecResponse, error) {
	// 获取命令和参数
	scriptContent := req.Parameters["script"]
	fullCmd := req.Parameters["command"]

	var executeContent string
	if scriptContent != "" {
		executeContent = scriptContent
		zaplog.Logger.Sugar().Infof("执行多行脚本: \n%s", executeContent)
	} else if fullCmd != "" {
		// 原有 command 参数处理（移除不必要的转义）
		executeContent = strings.ReplaceAll(fullCmd, `\"`, `"`)
		zaplog.Logger.Sugar().Infof("执行单条命令: %s", executeContent)
	} else {
		// 错误：未提供任何执行内容
		zaplog.Logger.Sugar().Errorf("未指定 command 或 script 参数")
		return &pb.ExecResponse{
			MachineId: req.MachineId,
			TaskId:    req.TaskId,
			Success:   false,
			Error: &pb.ErrorDetail{
				Code:    1000,
				Message: "必须指定 command（单条命令）或 script（多行脚本）参数",
			},
		}, nil
	}
	// 3. 使用shell执行命令（支持管道等特性）shell.go
	cmd := exec.Command("/bin/bash", "-c", executeContent)
	// 5. 捕获输出
	output, err := cmd.CombinedOutput()
	outputStr := string(output)

	// 6. 优化日志输出（避免打印二进制数组）
	if err != nil {
		zaplog.Logger.Sugar().Errorf("执行失败: %v\n输出: %s", err, outputStr)
		// 7. 返回响应
		return utils.ErrorResponse(req, 500, outputStr), nil // 注意：此处err为nil，告诉gRPC“RPC通信成功，业务执行失败”
	} else {
		zaplog.Logger.Sugar().Infof("执行成功\n输出: %s", outputStr)
	}

	// 7. 返回响应
	return &pb.ExecResponse{
		MachineId:      req.MachineId,
		TaskId:         req.TaskId, // 使用请求中的TaskId
		Success:        true,
		Stdout:         outputStr,
		Stderr:         "", // CombinedOutput已合并
		Change:         true,
		ChangedDetails: "执行命令: " + fullCmd,
		Error: &pb.ErrorDetail{
			Code:    0,
			Message: "",
			Trace:   "",
		},
	}, nil
}
func init() {
	Register("shell", NewShellModule) // 注册 "shell" 模块
}
